<?php

abstract class My_Controller_Action extends Zend_Controller_Action {

    const FORCE_AJAX_PARAM = 'x-force-ajax';

    /** @var Zend_Layout */
    protected $layout;

    /** @var Zend_Translate */
    protected $translator;
    protected $enableAjaxPacket = true;
    protected $ajaxStatus = 'OK';
    protected $ajaxPacket = array();
    protected $ajaxData = '';
    protected $printCurrentFlashMessages = false;
    protected $isColumn3 = true;

    /**
     *
     * @var array {email, user_id}
     */
    protected $user = null;

    /**
     *
     * @var integer
     */
    protected $userId = 0;
    protected $hasIdentity = false;
    protected $isUserActive = false;

    public function init() {
        parent::init();
        Zend_Registry::set('Controller', $this);
        $this->layout = Zend_Layout::getMvcInstance();
        $this->translator = Zend_Registry::get('Zend_Translate');

        $currentUser = Zend_Auth::getInstance()->getIdentity();
        $userId = $currentUser['user_id'];
        $daoUser = new Application_Model_DAO_User();
        $user = $daoUser->get($userId);
        My_Utils::setCurrentUser($user);
        $this->setCurrentUser($user);
        $controllerName = $this->getRequest()->getControllerName();
        $actionName = $this->getRequest()->getActionName();
        $isAllowed = $this->isAllowedAction($controllerName, $actionName);
        if($isAllowed !== true) {
            $this->_redirect($isAllowed);
        }
        Zend_Paginator::setDefaultItemCountPerPage(10);
        Zend_Paginator::setDefaultScrollingStyle();
        Zend_View_Helper_PaginationControl::setDefaultViewPartial('common/pagination-default.phtml');
    }
    
    /**
     * 
     * @param Zend_Db_Select|Zend_Db_Table_Select|array $list
     * @return Zend_Paginator
     */
    protected function createPaginator($list) {
        $paginator = Zend_Paginator::factory($list);
        $this->view->page = $page = intval($this->_getParam('page', 1));
        $paginator->setCurrentPageNumber($page);
        return $paginator;
    }

    public function url(array $routeParam, $route = 'default', $clear = true) {
        return $this->view->url($routeParam, $route, $clear);
    }

    public function setCurrentUser(array $user = null) {
        if ($user == null || empty($user)) {
            $this->user = null;
            $this->userId = 0;
            $this->hasIdentity = false;
            $this->isUserActive = false;
            $this->view->user = null;
            $this->view->userId = 0;
            $this->view->hasIdentity = false;
            $this->view->isUserActive = $this->isUserActive;
        } else {
            $this->user = $user;
            $this->userId = intval($user['user_id']);
            $this->hasIdentity = true;
            $this->isUserActive = $user['admin_active'] ? true : false;
            $this->view->user = $this->user;
            $this->view->userId = $this->userId;
            $this->view->hasIdentity = true;
            $this->view->isUserActive = $this->isUserActive;
        }
    }

    public function userLoginRequired($url = null) {
        if ($this->user != null) {
            return true;
        }
        if ($url == null) {
            $url = $this->_request->getRequestUri();
        }
        $this->saveURLWhileLogin($url);
        $redUrl = $this->url(array('controller' => 'user', 'action' => 'login', 'module' => 'default'));
        $this->_redirect($redUrl);
    }

    public function setContentTitle($msg, $translate = true) {
        if ($translate) {
            $msg = $this->_($msg);
        }
        $this->view->contentTitle = $msg;
    }

    /**
     *
     * @param string $controllerName
     * @param string $actionName 
     * @return misc state of access, true - action allowed; action denied: false - default action, string - url to redirect, const (int) - predefinied behaviour
     */
    public function isAllowedAction($controllerName, $actionName) {
        return true;
    }

    public function saveURLWhileLogin($url = null) {
        if (!$url) {
            $url = $_SERVER['REQUEST_URI'];
        }
        $session = new Zend_Session_Namespace('requestURL');
        $session->url = $url;
    }

    public function getURLWhileLogin() {
        $session = new Zend_Session_Namespace('requestURL');
        $url = isset($session->url) ? $session->url : null;
        $session->unsetAll();
        return $url;
    }

    public function translate($key) {
        $arg_list = func_get_args();
        $msg = $this->translator->_($key);
        if (count($arg_list) > 1) {
            array_splice($arg_list, 0, 1);
            $msg = sprintf($msg, $arg_list[0]);
        }
        return $msg;
    }

    public function _($key, array $data = null) {
        $msg = $this->translator->_($key);
        if ($data != null && !empty($data)) {
            $tmpkeys = array_keys($data);
            $vals = array_values($data);
            $keys = array();
            foreach ($tmpkeys as $tmpkey) {
                $keys[] = '%' . $tmpkey . '%';
            }
            $msg = str_replace($keys, $vals, $msg);
        }
        return $msg;
    }

    public function isPost() {
        return $this->_request->isPost();
    }

    public function isAjax() {
        $ajax = $this->_request->isXmlHttpRequest();
        if ($ajax) {
            return true;
        }
        if ($this->_hasParam(self::FORCE_AJAX_PARAM)) {
            if ($this->_getParam(self::FORCE_AJAX_PARAM) == '1') {
                return true;
            }
        }
        return false;
    }

    public function postDispatch() {
        if ($this->isAjax()) {
//            $this->setNoViewRenderer();
            $this->layout->disableLayout();
            if ($this->enableAjaxPacket) {
                $data = $this->createFlashMessagesData(true);
                $this->ajaxPacket += array('fm' => $data);
                $this->_helper->viewRenderer->postDispatch();
                $html = $this->getResponse()->getBody();
                $this->getResponse()->clearBody();
                if (!empty($html)) {
                    $this->ajaxPacket += array('html' => $html);
                }
                if (!empty($this->ajaxData)) {
                    $this->ajaxPacket += array('data' => $this->ajaxData);
                }
                $css = '' . $this->view->headLink();
                $js = $this->collectJavaScript($this->view->headScript()->getContainer());
//                d($js);
                if (!empty($css)) {
                    $this->ajaxPacket += array('css' => $css, 'js' => $js);
                }
                // @todo headscript && JS
                $this->sendJSON($this->ajaxPacket);
            }
        } else {
            if ($this->printCurrentFlashMessages) {
                $data = $this->createFlashMessagesData(true);
            } else {
                $data = $this->createFlashMessagesData();
            }
            $this->view->flashMessages = $data;
        }
        $this->view->columnRightContent = '';
        if (!$this->isAjax() && $this->isColumn3) {
            $this->view->isColumn3 = true;
            $this->view->columnRightContent = $this->getRightColumnContent();
        }
    }

    protected function getRightColumnContent() {
        return $this->view->render('adv/column-right.phtml');
    }

    /**
     * 
     * @param Zend_View_Helper_Placeholder_Container
     */
    protected function collectJavaScript(Zend_View_Helper_Placeholder_Container $container) {
        $arr = $container->getArrayCopy();
        $files = array();
        $codes = array();
        foreach ($arr as $obj) {
            if (empty($obj->source)) {
                $attr = $obj->attributes;
//                d($attr['src']);
                if (isset($attr['src'])) {
                    $files[] = $attr['src'];
                }
            } else {
                $codes[] = $obj->source;
            }
        }
        return array('files' => $files, 'code' => $codes);
    }

    protected function setPrintCurrentFlashMessages($printCurrentFlashMessages = true) {
        $this->printCurrentFlashMessages = $printCurrentFlashMessages;
    }

    protected function createFlashMessagesData($current = false, $clearCurrentMesages = true) {
        if ($current) {
            $msgs = $this->_helper->FlashMessenger->getCurrentMessages();
            if ($clearCurrentMesages) {
                $this->_helper->FlashMessenger->clearCurrentMessages();
            }
        } else {
            $msgs = $this->_helper->FlashMessenger->getMessages();
        }
        $data = array('info' => array(), 'success' => array(), 'error' => array(), 'warning' => array());
        foreach ($msgs as $v) {
            if (isset($v['type'])) {
                $data[$v['type']][] = $v['message'];
            } else {
                $data['info'][] = $v;
            }
        }
        return $data;
    }

    public function _redirect($url, array $options = array()) {
        if ($this->isAjax()) {
            $r = array('redirect' => $url);
            $data = $this->createFlashMessagesData(true, false);
            $this->ajaxPacket += $this->ajaxPacket + $r + $data;
            $this->sendJSON($this->ajaxPacket, true);
            return;
        }
        parent::_redirect($url, $options);
    }

    protected function sendJSON($data, $die = false) {
        if ($die) {
            if ($this->_hasParam(self::FORCE_AJAX_PARAM)
                    && $this->_getParam(self::FORCE_AJAX_PARAM) == '1'
                    && $this->isIE()) {
                // do not send content-type header, because it my cause to download the response
            } else {
                header('Content-type: application/json');   // trzeba uzyc low level api, bo die() spowoduje bezposrednie zakonczenie i zend nie wysle naglowkow
            }
        }
        $this->_response->setHeader('Content-Type', 'application/json', true);
//        d(Zend_Json::encode($data + array('status' => $this->ajaxStatus)));
        echo Zend_Json::encode($data + array('status' => $this->ajaxStatus));
        if ($die) {
            die();
        }
    }

    protected function isIE() {
        $userAgant = $_SERVER['HTTP_USER_AGENT'];
        if (stripos($userAgant, 'msie') !== false) {
            return true;
        }
        return false;
    }

    public function setNoViewRenderer($dontRenderView = true) {
        Zend_Controller_Front::getInstance()->setParam('noViewRenderer', $dontRenderView);
    }

    public function addSuccess($message) {
        $this->_helper->FlashMessenger->addMessage(array('type' => 'success', 'message' => $message));
    }

    public function addError($message) {
        $this->ajaxStatus = 'error';
        $this->_helper->FlashMessenger->addMessage(array('type' => 'error', 'message' => $message));
    }

    public function addWarning($message) {
        $this->_helper->FlashMessenger->addMessage(array('type' => 'warning', 'message' => $message));
    }

    public function addInfo($message) {
        $this->_helper->FlashMessenger->addMessage(array('type' => 'info', 'message' => $message));
    }

}
